<template>
  <!-- :class="[getHeight]" -->
  <div class="chat_room" ref="chatRoom" :style="{ height: state.chatRoomHeight + 'px' }">
    <div class="head" ref="head">
      <nut-navbar class="navbar" z-index="5" :clickable="false" fixed safe-area-inset-top>
        <template #content>
          <span class="head_content">{{ t('chat_with') }}:{{ state.userData.TUsername }}</span>
          <span class="head_content">({{ state.type || $t('official_customer_service') }})</span>
        </template>
        <template #left>
          <iconpark-icon @click="router.push('/chatList')" class="close" icon-id="tongyicontyfanh"
            size="2.4rem"></iconpark-icon>
        </template>
        <template #right>
        </template>
      </nut-navbar>
      <div class="placehoder"></div>
    </div>
    <div class="chat_content" :style="{ height: state.contentHeight + 'px' }" @click="state.isExpand = false">
      <div id="msg_list" class="msg_list">
        <div class="msg_item" v-for="(item, index) in state.chatMessagesList" :key="index"
          :class="[item.type === 'MessageTextContent' ? 'MessageTextContent' : item.type === 'MessageMoneyContent' ? 'MessageMoneyContent' : item.type === 'time' ? 'time' : item.type === 'newMsgLine' ? 'newMsgLine' : '', item.isUser ? 'is_user' : '']">
          <!-- user -->
          <div class="is_user" v-if="item.role !== 2 && (item.status != 'fail')">
            <div class="item_content">
              <!-- <view class="status" v-if="item.status == 'fail'">!</view> -->
              <div class="msg">
                <!-- 文字图片 -->
                <div class="text"
                  v-if="item.type === 'MessageTextContent' || item.type === 'MessagePicContent' || item.type === 'MessageVideoContent'"
                  @click="showPriview(item, index)">
                  <span class="text_msg" v-if="item.type === 'MessageTextContent'"
                    v-html="initMessage(item.content)"></span>
                  <!-- 图片视频审核提示 -->
                  <span class="text_msg"
                    v-if="(item.cstatus != 1 && item.type === 'MessagePicContent') || (item.cstatus != 1 && item.type === 'MessageVideoContent')">{{
                      item.type === 'MessagePicContent' ? t('image_review') : t('video_review') }}</span>
                  <ImgT v-else-if="item.type === 'MessagePicContent'" class="pic_msg"
                    :src="settings.upload_url + '/' + item.content" alt="" />
                  <video v-else-if="item.type === 'MessageVideoContent'" class="pic_msg"
                    :src="settings.upload_url + '/' + item.content" alt=""
                    :poster="isRealDevice(`${settings.upload_url + '/' + item.content}`)" />
                  <span class="text_time">{{ item.date }}</span>
                </div>
                <!-- 红包 -->
                <div class="hongbao" v-if="item.type === 'MessageMoneyContent'">
                  <div class="top">
                    <div class="left">
                      <div class="stranTo">{{ t('transfer_to') }}{{ item.transTo }}</div>
                      <div class="money">{{ item.money }}</div>
                    </div>
                    <ImgT class="right" src="/imgs/serviceModal/trans.webp" alt="" />
                  </div>
                  <div class="bottom">
                    <div class="trans_type">{{ item.transType }}</div>
                    <div class="item_time">({{ item.date }})</div>
                  </div>
                </div>
                <!-- 角 -->
                <div class="jiao" :class="[item.type === 'MessageMoneyContent' && 'MessageMoneyContent']"></div>
              </div>
              <div class="user_msg">
                <ImgT class="item_img" :src="`/imgs/head_icons/${state.userTHeadPhoto}.webp`" alt="" />
              </div>
            </div>
          </div>
          <!-- unuser -->
          <div class="unuser" v-if="item.role == 2 && (item.cstatus == 1)">
            <div class="item_content">
              <div class="msg">
                <!-- 文字图片 -->
                <div class="text"
                  v-if="item.type === 'MessageTextContent' || item.type === 'MessagePicContent' || item.type === 'MessageVideoContent'"
                  @click="showPriview(item, index)">
                  <span class="text_msg" v-if="item.type === 'MessageTextContent'"
                    v-html="initMessage(item.content)"></span>
                  <ImgT v-if="item.type === 'MessagePicContent'" class="pic_msg"
                    :src="settings.upload_url + '/' + item.content" alt="" />
                  <video v-if="item.type === 'MessageVideoContent'" class="pic_msg"
                    :src="settings.upload_url + '/' + item.content"
                    :poster="isRealDevice(`${settings.upload_url + '/' + item.content}`)" alt="" />
                  <span class="text_time">{{ item.date }}</span>
                </div>
                <!-- 红包 -->
                <div class="hongbao" v-if="item.type === 'MessageMoneyContent'">
                  <div class="top">
                    <div class="left">
                      <div class="stranTo">{{ t('transfer_to') }}{{ item.transTo }}</div>
                      <div class="money">{{ item.money }}</div>
                    </div>
                    <ImgT class="right" src="/imgs/serviceModal/trans.webp" alt="" />
                  </div>
                  <div class="bottom">
                    <div class="trans_type">{{ item.transType }}</div>
                    <div class="item_time">({{ item.date }})</div>
                  </div>
                </div>
                <!-- 角 -->
                <div class="jiao" :class="[item.type === 'MessageMoneyContent' && 'MessageMoneyContent']"></div>
              </div>
              <div class="user_msg">
                <ImgT class="item_img" :src="`/imgs/head_icons/${state.THeadPhoto}.webp`" alt="" />
                <div class="indent_type"
                  :class="['type' + (state.type == $t('official_customer_service') ? '1' : '-1')]">{{
                    state.type || $t('official_customer_service')
                  }}
                </div>
              </div>
            </div>
          </div>
          <!-- time标记时间 -->
          <div class="mark_time" v-if="item.msg_type == 'time'">
            {{ item.date }}
          </div>
          <!-- newMsgLine -->
          <div class="news_line" v-if="item.msg_type == 'newsLine'">
            <div class="left_line"></div>
            <div class="news_tip"> {{ item.text }}</div>
            <div class="right_line"></div>
          </div>
        </div>
        <!-- 预览图片视频 -->
        <nut-image-preview
          v-if="state.chatMessagesList[state.curPreviewIndex]?.type == 'MessagePicContent' || state.chatMessagesList[state.curPreviewIndex]?.type == 'MessageTextContent'"
          :show="state.showPreview" :images="previewSrc" closeable @close="state.showPreview = false" />
        <nut-image-preview v-else :show="state.showPreview" :videos="previewSrc" closeable
          @close="state.showPreview = false" />
      </div>
    </div>
    <div class="footer" ref="footer">
      <div class="questions" v-if="shortcutlist.length > 0">
        <scroll-view class="scroll-view" :scroll-x="true" style="width: 100%; white-space: nowrap;display: flex;">
          <template v-for="(item, index) in shortcutlist">
            <view class="item" @click="selectQuestionTab(index)">
              {{ item?.title }}
            </view>
          </template>
        </scroll-view>
      </div>
      <div class="footer_box">
        {{ state.contentHeight }}
        <div class="type_box">
          <nut-input @focus="handleFocus1" @blur="handleBlur" v-model="testMsg" ref="inputInstRef"
            :placeholder="t('input_consultation') + '～'" @click="scrollToBottom(500)">
            <template #right>
              <iconpark-icon style="margin: 0 8px;" icon-id="dibultktxs01" size="1.2rem"
                @click="openEmoji"></iconpark-icon>
              <iconpark-icon icon-id="dibultktxs04" size="1.2rem" @click="addHandler"></iconpark-icon>
            </template>
          </nut-input>
          <Btn class="send_btn" height="39px" width="100px" fontSize="16px" @click="sendMsg(1)">{{ t('home_page_send')
            }}
          </Btn>
        </div>
        <div class="expand" v-if="state.isExpand">
          <div class="expand_box">
            <div class="expand_list" v-if="state.expandType == 1">
              <div class="emoji">
                <EmojiPicker :native="true" @select="onSelectEmoji" />
              </div>
            </div>
            <div class="expand_list" v-if="state.expandType == 2">
              <template v-for="(item, index) in typeExpandList" :key="index">
                <div class="expand_item" @click="" v-if="[1, 2].includes(item.id) && item.show">
                  <nut-uploader :before-xhr-upload="beforeUpload" accept="image/*,video/*">
                    <iconpark-icon :icon-id="item.icon" size="1.2rem"></iconpark-icon>
                    <div class="text">
                      {{ item.text }}
                    </div>
                  </nut-uploader>
                </div>
                <div class="expand_item" @click="addItemHandler(item.id)" v-else-if="item.show">
                  <iconpark-icon :icon-id="item.icon" size="1.2rem"></iconpark-icon>
                  <div class="text">
                    {{ item.text }}
                  </div>
                </div>
              </template>
            </div>
            <div class="question_expand" v-if="state.expandType == 3">
              <scroll-view class="tabs_list">
                <template v-for="(item, index) in shortcutlist" :key="index">
                  <div class="tabs_item" :class="questionsIndex == index ? 'active' : ''"
                    @click="changeQuestionTabs(index)">
                    {{ item.title }}
                  </div>
                </template>
              </scroll-view>
              <scroll-view class="questionlist" v-if="shortcutlist[questionsIndex]?.list?.length > 0">
                <div class="ques_item" v-for="(item, index) in shortcutlist[questionsIndex].list" :key="index"
                  :class="questionsItemIndex == index ? 'active' : ''" @click="changeQuestionItem(item, index)">
                  {{ item }}
                </div>
              </scroll-view>
            </div>
          </div>
        </div>
      </div>
    </div>
    <!-- 转账 -->
    <Modal v-model:visible="isShowTransfer" :title="$t('transfer')">
      <div class="transfer popup_body">
        <div class="balance">{{ t('available_amount') }}：300.000.000.000</div>
        <div class="content">
          <div class="info">{{ t('transfer_amount') }}:</div>
          <nut-input type="number" clearable size="large" v-model="stransAmount"
            :placeholder="t('enter_transfer_amount')"></nut-input>
          <div class="info">{{ t('remark') }}:</div>
          <nut-textarea v-model="stransText" :placeholder="t('enter_transfer_remark')" :rows="6" />
          <div class="submit_btn">
            <Btn height="44px" v-shrink-on-click width="156px" class="submit" @click="handleTransfer">
              {{ t('transfer_now') }}
            </Btn>
          </div>
        </div>
      </div>
    </Modal>
  </div>
</template>

<script lang="ts" setup>
import { nextTick, onMounted, reactive, ref, watch, computed, onUnmounted } from 'vue';
import { useRoute, useRouter } from 'vue-router';
const route = useRoute();
import protobuf from 'protobufjs';
import { Buffer } from 'buffer';
import IWebsocket from '../chatWS.ts'
import usechatHooks from './useHooks.ts';
import usechatHooks2 from '../useHooks2.ts';
import EmojiPicker from 'vue3-emoji-picker'
import 'vue3-emoji-picker/css'
import { showToast } from "@nutui/nutui";
import { useI18n } from "vue-i18n";
import { storeToRefs } from 'pinia';
import { Chat } from '@/store/chat';
import { Page } from '@/store/page';
const page = Page();
const { settings } = storeToRefs(page);
const { usesrType, moneyauth, mutetype } = storeToRefs(Chat());
const chat = Chat();
const inputInstRef = ref()
const { t } = useI18n();
const router = useRouter();

// import pinia from '@/store/index';
// import { User } from '@/store/user';
// const userInfo = User(pinia);
// const { roleInfo } = storeToRefs(userInfo);
const roleInfo = JSON.parse(localStorage.getItem('roleInfo') || '')

const state: any = reactive({
  root: null,
  contentHeight: 0,
  chatRoomHeight: 0,
  messagetype: 1,//消息类型
  deviceID: roleInfo.id,// ,
  userTHeadPhoto: roleInfo.head_photo,// ,
  requestid: 5000, // 对方id
  todeviceid: 2651620, //对方设备ID

  THeadPhoto: '',
  name: null,
  type: null,
  expandType: 0,
  isExpand: false,
  chatMessagesList: [], // 聊天消息
  messageType: null,
  userData: '',
  imgValue: '',
  showPreview: false,
  curPreviewIndex: 0,
  shortCutTyptList: [], //快捷语分类
  quickPhrasesList: [] //快捷语列表
})
const preventDefault = () => {
  inputInstRef.value?.blur()
}
const handleFocus1 = () => {
  state.contentHeight = state.chatRoomHeight - footer.value.clientHeight - head.value.clientHeight - 100
  document.body.addEventListener('touchmove', preventDefault, { passive: false })
}
const handleBlur = () => {
  state.contentHeight = state.chatRoomHeight - footer.value.clientHeight - head.value.clientHeight - 55
  document.body.removeEventListener("touchmove", preventDefault,);
  window.scroll(0, 0)
}
const typeExpandList = computed(() => {
  return [
    { id: 1, icon: 'dbkujffkkz01', text: t('send_image'), show: true },
    { id: 2, icon: 'dbkujffkkz02', text: t('send_video'), show: true },
    { id: 3, icon: 'dbkujffkkz03', text: t('quick_reply'), show: true },
    { id: 4, icon: 'dbkujffkkz04', text: t('quick_reply_settings'), show: true },
    { id: 5, icon: 'dbkujffkkz05', text: t('transfer'), show: moneyauth.value },
  ]
})
const { getDateFromat, synchistorymsg, decodeContent, getShortcutCatelist, getShortcutCateMsg, getShortcutlist, getShortcutMsg, alreadread, keywordList, getkeywordList, keywordArr, initMessage }: any = usechatHooks(state)
const { startTimer }: any = usechatHooks2(state)
// 容器高度和padding
// const getHeight = computed(() => {
//   let height = ''
//   if (state.isExpand && shortcutlist.value.length > 0) {// 展开、有快捷语
//     height = 'height1'
//   } else if (state.isExpand && shortcutlist.value.length == 0) {// 展开、没快捷语
//     height = 'height1-1'
//   } else if (shortcutlist.value.length > 0) {//不展开 有快捷语
//     height = 'height2'
//   } else { // 不展开 没快捷语
//     height = 'height3'
//   }
//   return height
// })
// const footerHeight = computed(() => {
//   let height = ''
//   if (state.isExpand && shortcutlist.value.length > 0) {// 展开、有快捷语
//     height = '286px'
//   } else if (state.isExpand && shortcutlist.value.length == 0) {// 展开、没快捷语
//     height = '240px'
//   } else if (shortcutlist.value.length > 0) {//不展开 有快捷语
//     height = '118px'
//   } else { // 不展开 没快捷语
//     height = '72px'
//   }

//   return {
//     height
//   }
// })
// const contentHeight = computed(() => {
//   return {
//     height: `calc(100vh - 52px- 55px)`
//   }
// })
// const fIsMobile = () => {
//   return /Android|iPhone|iPad|iPod|BlackBerry|webOS|Windows Phone|SymbianOS|IEMobile|Opera Mini/i.test(navigator.userAgent);
// }

const isRealDevice = (imgStr: string) => { // pc web浏览器模拟器就默认支持ios吧，安卓的h5模拟器不管了，不影响用户
  const userAgent = navigator.userAgent.toLowerCase();
  if (navigator.maxTouchPoints && navigator.maxTouchPoints > 1) {//先区分模拟器还是真机
    if (userAgent.includes("android")) {//安卓真机
      return ''
    }
    return imgStr
  }
  return ''
}
// 问题列表
const questionsIndex = ref(0)
const questionsItemIndex = ref(0)
const selectQuestionTab = (index: any) => {
  state.isExpand = true
  questionsIndex.value = index
  state.expandType = 3
}
const changeQuestionTabs = (index: any) => {
  questionsIndex.value = index
}
const changeQuestionItem = (item: any, index: any) => {
  questionsItemIndex.value = index
  testMsg.value += item
}

//TODO: 编辑msg 表情发送形式跟pc要统一一下 以免收到的新消息list不一样
const testMsg = ref('')
const EmojiObj: any = reactive({})
const openEmoji = () => {
  state.isExpand = state.expandType == 1 ? !state.isExpand : true
  state.expandType = 1
}
const addHandler = () => {
  state.isExpand = state.expandType == 2 ? !state.isExpand : true
  state.expandType = 2
}

function onSelectEmoji(emoji: any) {
  console.log('emoji', emoji)
  // let img = `/:${emoji.r}:/`
  EmojiObj[emoji.i] = `/:${emoji.r}:/`
  testMsg.value = testMsg.value + emoji.i
}
// 转账
const isShowTransfer = ref(false)
const stransAmount = ref()
const stransText = ref('')
const handleTransfer = () => {
  console.log(1);
}
// 加号点击扩展功能
const addItemHandler = (id: any) => {
  switch (id) {
    case 3:
      selectQuestionTab(0)
      break;
    case 4:
      router.push({
        path: '/shortcut',
        query: {
          requestid: state.requestid
        }
      })
      break;
    case 5:
      isShowTransfer.value = true
      break;
    default:
      break;
  }
}

const msgTypeObj: any = {
  1: 'MessageTextContent',//文字消息
  2: 'MessageMoContent',//表情消息
  3: 'MessagePicContent', //图片
  4: 'MessageVideoContent',//视频
  5: 'MessageMoneyContent'//转账
}
// 发送消息 todo:跟pc同步一下格式
const sendMsg = (type: any) => {
  if (type == 1 && !(testMsg.value.trim())) {
    showToast.fail(t('content_required') + '!')
  }
  state.messagetype = type
  if (testMsg.value != '' || state.imgValue != '') {
    // 替换testMsg.value中所有表情键为EmojiObj中的值
    let processedMsg = testMsg.value;
    Object.keys(EmojiObj).forEach((key) => {
      processedMsg = processedMsg.replace(new RegExp(key, 'g'), EmojiObj[key]);
    });
    const type = 6; // 给用户发消息
    state.requestid++;
    const requestid = state.requestid;
    let inputMsg = state.imgValue ? state.imgValue : processedMsg
    const msginput = {
      data: inputMsg
    };
    //编码文字形式消息内容
    let MessageTextContentItem = state.root.lookupType('MessageTextContent')
    const errMsg1 = MessageTextContentItem.verify(msginput);
    if (errMsg1) throw new Error(errMsg1);
    const msginputdata = MessageTextContentItem.encode(MessageTextContentItem.create(msginput)).finish();
    var datatime = getDateFromat()
    const msgcontent = {
      fromdeviceid: state.deviceID,
      todeviceid: state.todeviceid,
      sendtime: datatime,
      mtype: state.messagetype,//文字类型消息
      data: msginputdata,
    };
    //编码消息体
    let MessageInputeItem = state.root.lookupType('MessageInpute')
    const errMsg2 = MessageInputeItem.verify(msgcontent);
    if (errMsg2) throw new Error(errMsg2);
    const msgcontentdata = MessageInputeItem.encode(MessageInputeItem.create(msgcontent)).finish();
    const params = {
      type: type,
      requestid: requestid,
      data: msgcontentdata,
    };
    const encodedRequest = encodeParams(params, 'Input')
    let InputItem = state.root.lookupType('Input')
    const buffer = Buffer.from(encodedRequest);
    const decodedMessage = InputItem.decode(buffer);
    const buffer1 = Buffer.from(decodedMessage.data);
    const decodedMessage1 = MessageInputeItem.decode(buffer1);
    const decoder = new TextDecoder('utf-8');
    const decodedString2 = decoder.decode(decodedMessage1.data);
    console.log("decodedMessage1.data :", decodedString2)
    if (state.messagetype == 1) {
      // 是否有敏感词判断 对自己是非客服
      if (state.messagetype == 1 && keywordArr.value.length && (!state.userData.deep || state.userData.iskf != 1)) {
        keywordArr.value.forEach((item: any) => {
          if (inputMsg && inputMsg.includes(item)) {
            inputMsg = inputMsg?.replace(new RegExp(item, 'g'), '*'.repeat(item.length))
          }
        })
      }
      state.chatMessagesList.push({ date: datatime, requestid, role: 1, cstatus: 1, content: inputMsg, name: '', type: msgTypeObj[state.messagetype] })
    } else {
      if (usesrType.value != 1) {// 发送图片视频不需要需要审核
        state.chatMessagesList.push({ date: datatime, requestid, role: 1, cstatus: 1, content: `${state.messagetype == 3 ? t('image_review') : t('video_review')}`, name: '', type: 'MessageTextContent' })
      } else {// 客服发送图片视频不需要需要审核 
        state.chatMessagesList.push({ date: datatime, requestid, role: 1, cstatus: 1, content: inputMsg, name: '', type: msgTypeObj[state.messagetype] })
      }
    }
    console.log('要发送的信息', state.deviceID, '=>', state.todeviceid, { date: datatime, role: 1, content: inputMsg, name: '', type: msgTypeObj[state.messagetype] })
    IWebsocket.sendMessageHandler(encodedRequest);
    testMsg.value = ''
    state.imgValue = ''
    // msgRef.value.innerHTML = ''
  }
}
// 编码发送参数
const encodeParams = (params: any, name: string) => {
  let item = state.root.lookupType(name)
  const errMsg = item.verify(params);
  if (errMsg) throw new Error(errMsg);
  const message = item.create(params);
  const buffer = item.encode(message).finish();
  return buffer;
}

const getChatMsgPublic = (data: any) => {
  const decodeobj2 = decodeContent(data.content, 'MessageOutpute')
  const decodeobj3 = decodeContent(decodeobj2.data, msgTypeObj[decodeobj2.mtype])
  console.log("onMessage/MessageTextContent output3 ", decodeobj3)
  const dealContent = (data: any) => {
    let res = data
    // 是否有敏感词判断 对自己是非客服需要
    if (keywordArr.value?.length && usesrType.value != 1) { //自己非客服
      keywordArr.value.forEach((item: any) => {
        if (data.includes(item)) {
          res = data?.replace(new RegExp(item, 'g'), '*'.repeat(item.length))
        }
      })
    }
    return res
  }

  const messageObj = {
    cstatus: data.msgtype == 1 ? 1 : data.cstatus,  // 1; // 通过 显示   等于0或者没有这个字段  就不能显示 (文字例外，违禁词显示***)
    msgtype: data.msgtype,
    date: decodeobj2.sendtime,   //时间
    role: decodeobj2.fromdeviceid == state.deviceID ? 1 : 2,   //角色1 我方消息 2 对方消息
    content: dealContent(decodeobj3.data),   //消息
    type: msgTypeObj[decodeobj2.mtype],
    name: decodeobj2.fromdeviceid == state.deviceID ? '' : state.userData.TUsername
  }
  if (state.messageType == 4) {    //获取到新消息
    state.chatMessagesList.push(messageObj)
    console.log('chatMessagesList新消息', state.chatMessagesList)
  } else { // 聊天记录
    state.chatMessagesList.unshift(messageObj)
    console.log('chatMessagesList', state.chatMessagesList)
  }
}
// 新消息
const getChatMsg4 = (decodeobj1: any, ServiceMessage: string) => {
  const decodeobj00 = decodeContent(decodeobj1.data, ServiceMessage)
  console.log("onMessage/ServiceMessage output1 ", decodeobj00)
  getChatMsgPublic(decodeobj00)

}
// 聊天历史
const getChatMsg2 = (decodeobj1: any, SyncResp: string) => {
  const decodeobj00 = decodeContent(decodeobj1.data, SyncResp);
  console.log("onMessage/SyncResp output4 ", decodeobj00)
  if (Object.keys(decodeobj00).length > 0) {
    if (Object.keys(decodeobj00.messages).length > 0) {
      decodeobj00.messages.forEach((item: any) => {
        getChatMsgPublic(item)
      })
    }
  } else {
    state.chatMessagesList = []
  }
}
//收到消息
const onMessage: any = async (buffer: any) => {
  const decodeobj1 = decodeContent(buffer, 'Output');
  console.log("onMessage/Output output0 ", decodeobj1)
  state.messageType = decodeobj1.type

  if (decodeobj1.code && decodeobj1.code > 1000) {
    showToast.fail(t(decodeobj1.code));
    // 失败id
    state.chatMessagesList.map((item: any) => {
      if (item.requestid == decodeobj1.requestid) {
        item.status = 'fail'
      }
    })
    return;
  }

  switch (decodeobj1.type) {
    case 6://给用户发送消息的，确定发送成功还是失败
      console.log(decodeobj1)
      break;
    case 4:// 获取到新消息
      getChatMsg4(decodeobj1, 'Message')
      // 收到新消息 
      startTimer(decodeobj1)
      break;
    case 8://消息同步触发,或者是历史消息
      getChatMsg2(decodeobj1, 'SyncResp')
      break;
    case 23://快捷语分类
      getShortcutCateMsg(decodeobj1)
      break;
    case 19://快捷列表数据
      getShortcutMsg(decodeobj1)
      break;
    case 28://获取关键词列表
      getkeywordList(decodeobj1)
      break;
    case 29://图片审核通过等
      state.chatMessagesList = []
      synchistorymsg()
      break;
    default:
      break;
  }
}
// 滚动
const newValue = computed(() => {
  if (state.chatMessagesList.length > 0) alreadread(state.chatMessagesList[state.chatMessagesList.length - 1])
  return state.chatMessagesList.length
})
const scrollToBottom = (v: any) => {
  nextTick(() => {
    setTimeout(() => {
      let element = document.getElementById('msg_list')
      console.log('scrollToBottom', element?.scrollHeight)
      element?.scrollTo(0, element.scrollHeight)
    }, v);
  })

}

// 上传图片视频
// 压缩图片
const compressFile = (file: any, { ratio }: any, callback: any) => {
  let fileObj = file
  let reader = new FileReader()
  reader.readAsDataURL(fileObj) // 转base64
  reader.onload = function (e) {
    let image: any = new Image() // 新建一个img标签（还没嵌入DOM节点)
    image.src = e?.target?.result
    image.onload = function () {
      let canvas = document.createElement('canvas')
      let context = canvas.getContext('2d')
      let imageWidth = image.width * ratio
      let imageHeight = image.height * ratio
      let data = ''
      canvas.width = imageWidth
      canvas.height = imageHeight
      context?.drawImage(image, 0, 0, imageWidth, imageHeight)
      data = canvas.toDataURL('image/jpeg') // 输出压缩后的base64
      let arr = data.split(',')
      let mime: any = arr[0]?.match(/:(.*?);/)?.[1] // 转成blob
      let bstr = atob(arr[1])
      let n = bstr.length
      let u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      const lastIndex = fileObj.name.lastIndexOf('.')
      const newName = fileObj.name.slice(0, lastIndex)
      let files = null
      try {
        // 这儿存在兼容性问题
        files = new window.File([new Blob([u8arr], { type: mime })], `${newName}.jpeg`, { type: 'image/jpeg' }) // 转成file
      } catch (e) {
        files = file
      }
      callback(files, { imageWidth, imageHeight }) // 回调
    }
  }
}
const beforeUpload = async (xhr: any, data: any) => {
  await chat.getConfig() // 获取角色
  console.log(xhr)
  console.log('beforeUploaddata', data.sourceFile)
  const file = data.sourceFile
  const type = file.type.includes('image') ? 'image' : file.type.includes('video') ? 'video' : ''
  // 查权限
  if (mutetype.value.type_id === 1) {
    showToast.fail(t('mute'))
    return
  }
  if (file && file.size > 1024 * 1024 * 10 && type == 'image') { // 10MB限制
    showToast.fail(t('file_size_exceeded'))
    return;
  }
  if (file && file.size > 1024 * 1024 * 100 && type == 'video') { // 100MB限制
    showToast.fail('文件大小不能超过100MB！')
    return;
  }
  if (type == 'image') {
    const allowedTypes = ['image/png', 'image/jpeg', 'image/jpg']; // Allow only PNG and JPEG
    if (!allowedTypes.includes(file.type)) {
      showToast.fail(t('image_format_error'));
      state.isExpand = false
      return;
    }
  }
  if (type === 'image' && file.size > 1024 * 1024 * 2 && file.size <= 1024 * 1024 * 10) { // 如果图片大于2MB且小于10MB，进行压缩
    let ratio = 1
    if (file.size > 8 * 1024 * 1024) { // 8-10M
      ratio = 1 / 18
    } else if (file.size > 6 * 1024 * 1024) { // 6-8M
      ratio = 1 / 16
    } else if (file.size > 4 * 1024 * 1024) { // 4-6M
      ratio = 1 / 14
    } else if (file.size > 2 * 1024 * 1024) { // 2-4M
      ratio = 1 / 12
    } else if (file.size > 1 * 1024 * 1024) { // 1-2M
      ratio = 1 / 4
    } else if (file.size > 0.5 * 1024 * 1024) { // 500kb-1M
      ratio = 1 / 2
    }
    compressFile(file, { ratio }, (resFile: any) => {
      uploadFile(resFile, type)
    })
  } else {
    uploadFile(file, type); // 小于2MB或大于10MB直接上传
  }
}
// 上传文件
const uploadFile = (file: File, type: string) => {
  const formData = new FormData();
  formData.append(type, file);
  formData.append('deviceid', state.deviceID);
  state.isExpand = false
  fetch(settings.value.upload_url + `/api/upload/${type == 'image' ? 'img' : 'video'}`, {
    method: 'POST',
    body: formData,
  })
    .then(response => response.json()).then((response: any) => {
      if (response.status == 'success' || response.code == 200) {
        const urlImg = response.data.path
        state.imgValue = urlImg;
        state.messagetype = type == 'image' ? 3 : 4
        sendMsg(state.messagetype)
      }
    }).catch(() => {
      showToast.fail(t('send_failed'))
    })
};
const previewSrc = computed(() => {
  let arr = []
  arr = state.chatMessagesList.map((i: any) => {
    let obj = {}
    if (i.type == 'MessageTextContent') {
      // 查找text中是否有img 取他的src 做预览
      let regex = /<img\s+src="([^"]*)"/;
      let match = i.content.match(regex);
      if (match) {
        obj = { src: match[1] };
      }
    } else if (i.type == 'MessagePicContent') {
      obj = { src: settings.value.upload_url + '/' + i.content }
    } else {
      obj = {
        source: {
          src: settings.value.upload_url + '/' + i.content,
          type: 'video/mp4'
        },
        options: {
          muted: true,
          controls: true
        }
      }
    }
    return [obj]
  })
  return arr[state.curPreviewIndex]
})
const showPriview = (item: any, index: any) => {
  if (item.type == 'MessageTextContent') {
    // 查找text中是否有img 没有就不展示图片
    let regex = /<img\s+src="([^"]*)"/;
    let match = item.content.match(regex);
    if (!match) return
  }
  state.curPreviewIndex = index
  state.showPreview = true
}
const onOpen = () => {
  const type = 1; // PT_SIGN_IN
  console.log('state.requestid', state.requestid)
  const requestid = 5000;
  const singin = {
    deviceid: state.deviceID,//用户的roleid
    userid: state.deviceID,//用户的roleid
    token: 'mmssdfasd1155',// Local.get('user').token,//后期从另外一个项目中获取
  }
  const data = encodeParams(singin, 'SignInInput')
  const params = {
    type: type,
    requestid: requestid,
    data: data,
  };
  const encodedRequest = encodeParams(params, 'Input')
  IWebsocket.sendMessageHandler(encodedRequest);
}
// 快捷语
const shortcutlist = computed(() => {
  let arr = []
  arr = state.shortCutTyptList.map((item: any) => {
    let list: any = []
    state.quickPhrasesList.map((it: any) => {
      if (it.qhcid === item.id) {
        list.push(it.content)
      }
    })
    item.list = list
    return item
  })
  console.log('arr', arr)
  return arr
})
const handleFun = () => {
  if (document.visibilityState === 'visible') {
    if (IWebsocket.instance == null) init();
  }
}
const init = async () => {
  const roleInfo = JSON.parse(localStorage.getItem('roleInfo') || '')
  state.deviceID = Number(roleInfo.id || localStorage.getItem('deviceid'))
  document.documentElement.style.overflow = 'hidden'
  document.body.style.overflow = 'hidden';
  state.userData = JSON.parse(route.query.userInfo as string)
  state.todeviceid = state.userData.Tdeviceid
  state.THeadPhoto = state.userData.THeadPhoto
  state.type = route.query.type
  state.chatMessagesList = []
  console.log('进入,selectedchatItem', state.userData)
  if (IWebsocket.instance == null) {
    IWebsocket.conectWebsocket()
  }
  state.root = await protobuf.load('/connect.ext.proto');
  onOpen()
  IWebsocket.resgisterHandler(onMessage)
  // 获取聊天记录
  synchistorymsg()
  // 获取快捷语
  getShortcutCatelist()
  getShortcutlist()
  keywordList()
}
const chatRoom = <any>ref(null);
const footer = <any>ref(null);
const head = ref()

onMounted(async () => {
  setTimeout(() => {
    state.chatRoomHeight = window.innerHeight
    state.contentHeight = state.chatRoomHeight - footer.value.clientHeight - head.value.clientHeight - 55
  }, 100);
  init()
  // 息屏重连
  document.addEventListener('visibilitychange', handleFun);
})
onUnmounted(() => {
  document.documentElement.style.overflow = 'visible'
  document.body.style.overflow = 'visible';
  document.removeEventListener('visibilitychange', handleFun)
  document.body.removeEventListener("touchmove", preventDefault,);
})
watch(newValue, () => {
  // document.documentElement.style.overflow = 'visible'
  // document.body.style.overflow = 'visible';
  scrollToBottom(1000)
  alert(11)
  // window.scroll(0, 0)
  // document.documentElement.style.overflow = 'hidden'
  // document.body.style.overflow = 'hidden';
})
watch(
  () => state.isExpand,
  () => {
    scrollToBottom(500)
    alert(111)
    // setTimeout(() => {
    // state.contentHeight = state.chatRoomHeight - footer.value.clientHeight - head.value.clientHeight - 10
    // }, 100);
  })

</script>

<style lang="scss" scoped>
.chat_room {
  // border: 1px solid red;
  // height: 90vh;
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
  // padding-top: calc(constant(safe-area-inset-top));
  // padding-top: calc(env(safe-area-inset-top));



  // &.height1 {
  //   padding-bottom: calc(constant(safe-area-inset-bottom) + 296px + 10px);
  //   padding-bottom: calc(env(safe-area-inset-bottom) + 296px + 10px);
  // }

  // &.height1-1 {
  //   padding-bottom: calc(constant(safe-area-inset-bottom) + 250px + 10px);
  //   padding-bottom: calc(env(safe-area-inset-bottom) + 250px + 10px);
  // }

  // &.height2 {
  //   padding-bottom: calc(constant(safe-area-inset-bottom) + 118px + 10px);
  //   padding-bottom: calc(env(safe-area-inset-bottom) + 118px + 10px);
  // }

  // &.height3 {
  //   padding-bottom: calc(constant(safe-area-inset-bottom) + 72px + 10px);
  //   padding-bottom: calc(env(safe-area-inset-bottom) + 72px + 10px);
  // }

}

.head {
  position: fixed;
  top: 0;
  padding-top: constant(safe-area-inset-top);
  padding-top: env(safe-area-inset-top);
  width: 100%;
  height: 55px;
  // background-color: #361e79;
  z-index: 1;

  .close {
    z-index: 6;
  }


  .navbar {
    position: fixed;
  }

  .placehoder {
    height: 55px;
  }

  .head_content {
    max-width: 200px;
    overflow: auto;
    text-wrap: nowrap;
    margin-right: 10px;
  }
}

.chat_content {
  color: #fff;
  transition: height 0.5s;
  overflow: hidden;
  padding: 0 10px 0;
  // height: calc(100vh - 100px - 55px);
  margin-top: 65px;
  // border: 1px solid yellow;

  // &.has {
  //   height: calc(100vh - 142px - 55px);
  // }

  .msg_list {
    overflow-y: auto;
    height: 100%;
    // border: 1px solid #1266ff;
    padding-bottom: 10px;

    .msg_item {
      width: 100%;

      .is_user {

        .item_content {
          padding-left: 35px;
          display: flex;
          justify-content: end;
          margin-top: 10px;

          .status {
            background: #E51F1F;
            color: white;
            border-radius: 50%;
            width: 20px;
            height: 20px;
            line-height: 20px;
            text-align: center;
            margin-right: 10px;
            margin-top: 20px;
          }

          .msg {
            max-width: 280px;
            position: relative;

            .jiao {
              position: absolute;
              right: 3px;
              top: 10px;
              border-bottom: 8px solid transparent;
              border-top: 8px solid transparent;
              border-left: 8px solid #412d98;

              &.hongbao {
                right: -6px;
                width: 0;
                height: 0;
                border-left: 8px solid #E82727;
              }

            }

            .text {
              background-color: #412d98;
              border-radius: 10px;
              margin-right: 10px;
              padding: 10px 6px 10px 10px;
              display: flex;
              flex-direction: column;

              .text_msg {
                word-break: break-all;

                :deep(img) {
                  max-width: 200px;
                  max-height: 200px;
                }
              }

              .pic_msg {
                max-width: 100px;
                max-height: 100px;
              }

              .text_time {
                font-size: 10px;
                color: #897bc7;
                padding-left: 4px;
                width: 100%;
                height: 10px;
                text-align: right;
              }
            }

            .hongbao {
              width: 270px;
              background-image: linear-gradient(to bottom, #EC3232, #E62121), linear-gradient(to right, #E51D1D, #E51D1D);
              border-radius: 10px;
              margin-right: 10px;
              overflow: hidden;


              .top {
                display: flex;
                justify-content: space-between;
                align-items: center;
                font-size: 14px;
                color: #fff;
                height: 58px;
                padding: 0 10px;

                .left {
                  .stranTo {
                    font-size: 16px;
                  }

                  .money {
                    line-height: 24px;
                  }
                }

                .right {
                  width: 48px;
                }

              }

              .bottom {
                padding: 0 10px;
                background: #fff;
                height: 24px;
                display: flex;
                justify-content: space-between;
                color: #000;

                .item_time {
                  font-size: 12px;
                  line-height: 24px;
                  color: #888997;
                }
              }

            }

          }

          .user_msg {
            .item_img {
              height: 40px;
              width: 40px;
            }
          }
        }
      }

      .unuser {

        .item_content {
          padding-right: 35px;
          display: flex;
          flex-direction: row-reverse;
          justify-content: start;
          margin-top: 14px;

          .msg {
            max-width: 280px;
            position: relative;

            .jiao {
              position: absolute;
              left: 4px;
              top: 10px;
              border-bottom: 8px solid transparent;
              border-top: 8px solid transparent;
              border-right: 8px solid #3EA473;

              &.hongbao {
                left: -6px;
                width: 0;
                height: 0;
                border-right: 8px solid #E82727;
              }

            }

            .text {
              background-color: #3EA473;
              border-radius: 10px;
              margin-left: 10px;
              padding: 10px 10px 10px 10px;
              display: flex;
              flex-direction: column;

              .pic_msg {
                max-width: 100px;
                max-height: 100px;
              }

              .text_msg {
                word-break: break-all;

                :deep(img) {
                  max-width: 200px;
                  max-height: 200px;
                }
              }

              .text_time {
                font-size: 10px;
                color: #b7d1c4;
                padding-left: 4px;
                width: 100%;
                height: 10px;
                text-align: right;
              }
            }

            .hongbao {
              width: 270px;
              background-image: linear-gradient(to bottom, #EC3232, #E62121), linear-gradient(to right, #E51D1D, #E51D1D);
              border-radius: 10px;
              margin-left: 10px;
              overflow: hidden;


              .top {
                display: flex;
                justify-content: space-between;
                align-items: center;
                font-size: 14px;
                color: #fff;
                height: 58px;
                padding: 0 10px;

                .left {
                  .stranTo {
                    font-size: 16px;
                  }

                  .money {
                    line-height: 24px;
                  }
                }

                .right {
                  width: 48px;
                }

              }

              .bottom {
                padding: 0 10px;
                background: #fff;
                height: 24px;
                display: flex;
                justify-content: space-between;
                color: #000;

                .item_time {
                  font-size: 12px;
                  line-height: 24px;
                  color: #888997;
                }
              }

            }

          }

          .user_msg {
            .item_img {
              height: 40px;
              width: 40px;
            }

            .indent_type {
              font-size: 10px;
              border-radius: 20px;
              padding: 0 4px;
              border-image-slice: 1;
              white-space: nowrap;
              max-width: 60px;
              overflow: hidden;
              text-wrap: nowrap;
              text-overflow: ellipsis;

              &.type0 {
                border-image-source: linear-gradient(to bottom, #fff 0%, #8cacff 103%);
                background-image: linear-gradient(to right, #4c36b3 0%, #3c279a 100%), linear-gradient(to bottom, #fff 0%, #8cacff 103%);
              }

              &.type-1 {
                border-image-source: linear-gradient(to bottom, #ffc38e 0%, #ff7b4c 103%);
                background-image: linear-gradient(88deg, #f92 0%, #da4212 99%), linear-gradient(to bottom, #ffc38e 0%, #ff7b4c 103%);
              }

              &.type1 {
                border-image-source: linear-gradient(to bottom, #6bcdff 0%, #5e99ff 103%);
                background-image: linear-gradient(88deg, #12b8ff 0%, #1266ff 99%), linear-gradient(to bottom, #6bcdff 0%, #5e99ff 103%);
              }

            }
          }
        }
      }

      .mark_time {
        width: 100%;
        height: 18px;
        font-size: 12px;
        color: #a2a5de;
        text-align: center;
        margin-top: 10px;
      }

      .news_line {
        width: 100%;
        height: 18px;
        color: #a2a5de;
        font-size: 12px;
        color: #a2a5de;
        margin-top: 10px;
        display: flex;
        align-items: center;
        justify-content: space-between;

        .left_line {
          width: 143px;
          height: 1px;
          background-image: linear-gradient(to right, rgba(162, 165, 222, 0), #a2a5de);
        }

        .right_line {
          width: 143px;
          height: 1px;
          background-image: linear-gradient(to right, #a2a5de, rgba(162, 165, 222, 0));
        }

      }
    }
  }
}

.footer {
  position: fixed;
  // border: 1px solid green;
  padding-bottom: constant(safe-area-inset-bottom);
  /*兼容 IOS<11.2*/
  padding-bottom: env(safe-area-inset-bottom);
  /*兼容 IOS>11.2*/
  transition: height 0.5s;
  bottom: 0;
  z-index: 9;
  background-color: #000;

  .questions {
    width: 100vw;
    overflow: hidden;
    margin: 10px 0;

    .scroll-view {
      .item {
        height: 24px;
        margin-left: 10px;
        padding: 4px 10px;
        line-height: 24px;
        border-radius: 6px;
        background-color: #412d98;
        font-size: 12px;
        color: #fff;
      }
    }
  }

  .footer_box {
    box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.39), 0 2px 2px 0 rgba(0, 0, 0, 0.34), 0 5px 3px 0 rgba(0, 0, 0, 0.2), 0 8px 3px 0 rgba(0, 0, 0, 0.06), 0 13px 3px 0 rgba(0, 0, 0, 0.01);
    background-image: linear-gradient(to bottom, #301a73, #1e0f46), radial-gradient(circle at 50% 14%, #4c36b3 0%, #3a2786 61%, #3c279a 82%);


    .type_box {
      height: 72px;
      width: 375px;
      padding: 14px;
      display: flex;
      justify-content: space-between;
      align-items: center;

      &:deep(.nut-input) {
        width: 267px;
        height: 32px;
        padding: 4px 10px;
        border-radius: 15px;
        border: solid 1px #322c59;
        background-color: #1f2032;

        input {
          &::placeholder {
            color: #8d84c5;
          }

        }
      }

      .send_btn {
        border-radius: 12px;
        overflow: hidden;
        width: 70px;
        height: 32px;
        border-radius: 20px;
        background: url(/imgs/serviceModal/sendbtn.webp) no-repeat;
        background-size: 100% 100%;
        font-size: 12px;
        text-align: center;
        color: #fff;

        :deep(img) {
          display: none;
        }
      }
    }
  }

  .expand {
    padding: 0 10px;

    .expand_box {
      border-top: 2px solid #201844;
      height: 180px;
      font-size: 12px;
      color: #fff;

      .expand_list {
        padding-top: 16px;
        width: 100%;
        display: flex;
        justify-content: space-around;

        .expand_item {
          width: 64px;
          height: 62px;
          border-radius: 6px;
          background-color: #1f2032;
          display: flex;
          flex-direction: column;
          justify-content: space-between;
          padding: 8px 1px 7px;
          align-items: center;
        }

        :deep(.nut-uploader__slot) {
          height: 47px;
          display: flex;
          flex-direction: column;
          justify-content: space-between;
          align-items: center;
        }

        :deep(.nut-uploader__preview) {
          display: none !important;
        }
      }

      .question_expand {
        padding-top: 10px;
        display: flex;

        .tabs_list {
          width: 68px;
          height: 152px;

          .tabs_item {
            border-radius: 6px;
            margin-bottom: 6px;
            background-color: #1f2032;
            text-align: center;
            min-height: 24px;
            line-height: 24px;

            &.active {
              background-color: #412d98;

            }
          }
        }

        .questionlist {
          max-height: 152px;
          width: 275px;
          margin-left: 10px;
          border-radius: 10px;


          .ques_item {
            width: 275px;
            height: 31px;
            background-color: #1f2032;
            text-align: center;
            line-height: 31px;

            &.active {
              background-color: #412d98;
            }
          }
        }

      }
    }
  }

  .expand:has(.expand_box .expand_list .emoji) {
    padding: 0;

    .expand_list {
      padding: 0;
    }
  }
}

.transfer {
  color: #fff;


  .balance {
    padding: 20px 0 0;
    width: 100%;
    text-align: center;
    font-size: 14px;
  }

  .content {
    padding: 0 32px;

    .info {
      margin: 20px 0 6px;
    }

    .submit_btn {
      width: 100%;
      padding: 24px 0;
      display: flex;
      justify-content: space-around;
    }
  }

  .nut-textarea {
    box-shadow: 0px 4px 4px 0px #00000040 inset;
    border-radius: 8px;
    border-bottom: unset;
    display: flex;
    justify-content: center;
    background: #27155C;
    background-blend-mode: overlay;
    padding: 10px;
    background: radial-gradient(50% 208.33% at 50% 50%, rgba(126, 126, 126, 0.32) 0%, rgba(21, 21, 21, 0.32) 100%);
    background: linear-gradient(180deg, rgba(0, 0, 0, 0.02) 0%, rgba(0, 0, 0, 0.1) 100%);

    &:deep(.input-text) {
      text-align: center !important;
    }

    &:deep(.nut-textarea__textarea) {
      color: #ffffff;

      &::placeholder {
        color: #87a1ce;

      }
    }
  }

  .nut-input {
    width: 100%;
    background: #27155C;
    // border: 1px solid #322c59;
    border-radius: 8px;
    padding: 9px 8px;
  }
}

:deep() {
  .nut-navbar {

    .nut-navbar__left,
    .right-handler {
      color: #fff;
    }
  }
}

.emoji {
  &:deep(.v3-emoji-picker) {
    border-radius: unset;
    width: 375px;
    height: 180px;

    .v3-header {
      padding: 5px 15px;
    }

    .v3-body {
      height: 200px;
      padding: 0 0 4px 10px;
    }

    .v3-spacing,
    .v3-search,
    .v3-sticky,
    .v3-footer {
      display: none;
    }
  }
}

.show_prive {
  display: block;
}
</style>